#include "CParse.h"
#include <string>
#ifdef _DEBUG
#include <iostream>
#endif
using namespace std;
using namespace MyRegular_Parse;
bool CParse::CheckNumStr( const char* pszSource ){
	while( *pszSource != 0x00 ){
		if( !isdigit( *pszSource++ ) )
			return false;
	}
	return true;
}
int CParse::BraceParse(){
	if( '{' != token.Token() )
		return ERC_Ingor;
	if( ECTT_String != token.GetNextToken() ){
		return ERC_Failed;
	}
	if( !CheckNumStr( token.GetTokenString().c_str() ) )
		return ERC_Failed;
	int iMin = 0, iMax = 0;
	iMin = atoi( token.GetTokenString().c_str() );
	if( ',' != token.GetNextToken() )
		return ERC_Failed;
	if( ECTT_String != token.GetNextToken() ){
		return ERC_Failed;
	}
	if( !CheckNumStr( token.GetTokenString().c_str() ) )
		return ERC_Failed;
	iMax = atoi( token.GetTokenString().c_str() );
	if( '}' != token.GetNextToken() )
		return ERC_Failed;
	msg.Loop( iMin, iMax );
	return ERC_OK;
}
int CParse::ParenthesisParse(){
	if( '(' != token.Token() )
		return ERC_Ingor;
	msg.BeginParenthesis();
	if( ERC_Failed == _Parse( ( ECTokenType )')' ) )
		return ERC_Failed;
	if( ')' != token.Token() )
		return ERC_Failed;
	msg.EndParsethesis();
	return ERC_OK;
}
int CParse::BracketParse(){
	if( '[' != token.Token() )
		return ERC_Ingor;
	msg.BeginBracket();
	string strBefore;
	int iAryMinus[ 2 ];
	bool bMinusEnable = false;
	int itoken;
	while( itoken = token.GetNextToken() ){
		if( '-' == token.Token() ){
#if _MSC_VER == 1700 
			iAryMinus[ 0 ] = strBefore.back();
			strBefore.pop_back();
#else
			iAryMinus[ 0 ] = strBefore[ strBefore.size() - 1 ];
			strBefore.erase( strBefore.end() - 1 );
#endif
			if( strBefore.size() )
				msg.Bracket( strBefore.c_str() );
			bMinusEnable = true;
		}
		else
		if( ECTT_String == itoken ){
			if( bMinusEnable ){
				if( token.GetTokenString().empty() )
					return ERC_Failed;
				iAryMinus[ 1 ] = token.GetTokenString().at( 0 );
				bMinusEnable = false;
				strBefore = token.GetTokenString().c_str() + 1;
				msg.Bracket( iAryMinus[ 0 ], iAryMinus[ 1 ] );
			}
			else{
				strBefore = token.GetTokenString();
			}
		}
		else
		if( itoken > ECTT_StartMark && itoken < ECTT_String ){
			if( strBefore.size() )
				msg.Bracket( strBefore.c_str() );
			msg.Specify( itoken );
		}
		else
			break;
	}
	if( ']' != token.Token() )
		return ERC_Failed;
	if( strBefore.size() )
		msg.Bracket( strBefore.c_str() );
	msg.EndBracket();
	return ERC_OK;
}
int CParse::Parse( const char* pszSource ){
	token.InitTokenEnv( pszSource );
	return _Parse( ECTT_END );
}
int CParse::L(){
	switch( token.Token() ){
	case '[':
		return BracketParse();
	case '(':
		return ParenthesisParse();
	default:
		if( ( token.Token() > ECTT_StartMark ) && ( token.Token() < ECTT_END ) ){
			if( token.Token() == ECTT_String )
				msg.String( token.GetTokenString().c_str() );
			else
				msg.Specify( token.Token() );
		}
		return ERC_OK;
	}
	return ERC_Ingor;
}
int CParse::R(){
	switch( token.GetNextToken() ){
	case '?': msg.Loop( 0, 1 ); return ERC_OK;
	case '*': msg.Loop( 0, -1 ); return ERC_OK;
	case '+': msg.Loop( 1, -1 ); return ERC_OK;
	case '{':
		return BraceParse();
	}
	return ERC_Ingor;
}
int CParse::_Parse( ECTokenType eEnd /* = ECTT_END*/ ){
	int ect = eEnd;
	token.GetNextToken();
	while( token.Token() != eEnd ){
		if( L() == ERC_OK ){
			if( R() == ERC_OK )
				token.GetNextToken();
		}
		else{
			return ERC_Failed;
		}
	}
	return ERC_OK;
}
void CTestParse::Test( const char* pszSource ){
	CParse parse;
	parse.Parse( pszSource );
}